/**
 * Created by gadflybsd on 2017/3/20.
 */
/*
 * SimplePubSub from https://github.com/mbenford/ngTagsInput/blob/master/src/util.js
 * */
'use strict';

function SimplePubSub() {
	var events = {};
	return {
		on: function(names, handler) {
			names.split(' ').forEach(function(name) {
				if (!events[name]) {
					events[name] = [];
				}
				events[name].push(handler);
			});
			return this;
		},
		trigger: function(name, args) {
			angular.forEach(events[name], function(handler) {
				handler.call(null, args);
			});
			return this;
		}
	};
};

angular.module('tabSlideBox', [])
	.directive('onFinishRender', function ($timeout) {
		return {
			restrict: 'A',
			link: function (scope, element, attr) {
				if (scope.$last === true) {
					$timeout(function () {
						scope.$emit('ngRepeatFinished');
					});
				}
			}
		}
	})
	.directive('tabSlideBox', [ '$timeout', '$window', '$ionicSlideBoxDelegate', '$ionicScrollDelegate',
		function($timeout, $window, $ionicSlideBoxDelegate, $ionicScrollDelegate) {
			'use strict';

			return {
				restrict : 'A, E, C',
				link : function(scope, element, attrs, ngModel) {

					var ta = element[0], $ta = element;
					$ta.addClass("tabbed-slidebox");
					if(attrs.tabsPosition === "bottom"){
						$ta.addClass("btm");
					}

					//Handle multiple slide/scroll boxes
					var handle = ta.querySelector('.slider').getAttribute('delegate-handle');

					var ionicSlideBoxDelegate = $ionicSlideBoxDelegate;
					if(handle){
						ionicSlideBoxDelegate = ionicSlideBoxDelegate.$getByHandle(handle);
					}

					var ionicScrollDelegate = $ionicScrollDelegate;
					if(handle){
						ionicScrollDelegate = ionicScrollDelegate.$getByHandle(handle);
					}

					function renderScrollableTabs(){
						var iconsDiv = angular.element(ta.querySelector(".tsb-icons")), icons = iconsDiv.find("a"), wrap = iconsDiv[0].querySelector(".tsb-ic-wrp"), totalTabs = icons.length;
						var scrollDiv = wrap.querySelector(".scroll");

						angular.forEach(icons, function(value, key){
							var a = angular.element(value);
							a.on('click', function(){
								ionicSlideBoxDelegate.slide(key);
							});

							if(a.attr('icon-off')) {
								a.attr("class", a.attr('icon-off'));
							}
						});

						var initialIndex = attrs.tab;
						//Initializing the middle tab
						if(typeof attrs.tab === 'undefined' || (totalTabs <= initialIndex) || initialIndex < 0){
							initialIndex = Math.floor(icons.length/2);
						}

						//If initial element is 0, set position of the tab to 0th tab 
						if(initialIndex == 0){
							setPosition(0);
						}

						$timeout(function() {
							ionicSlideBoxDelegate.slide(initialIndex);
						}, 0);
					}
					function setPosition(index){
						var iconsDiv = angular.element(ta.querySelector(".tsb-icons")), icons = iconsDiv.find("a"), wrap = iconsDiv[0].querySelector(".tsb-ic-wrp"), totalTabs = icons.length;
						var scrollDiv = wrap.querySelector(".scroll");

						var middle = iconsDiv[0].offsetWidth/2;
						var curEl = angular.element(icons[index]);
						var prvEl = angular.element(iconsDiv[0].querySelector(".active"));
						if(curEl && curEl.length){
							var curElWidth = curEl[0].offsetWidth, curElLeft = curEl[0].offsetLeft;

							if(prvEl.attr('icon-off')) {
								prvEl.attr("class", prvEl.attr('icon-off'));
							}else{
								prvEl.removeClass("active");
							}
							if(curEl.attr('icon-on')) {
								curEl.attr("class", curEl.attr('icon-on'));
							}
							curEl.addClass("active");

							var leftStr = (middle  - (curElLeft) -  curElWidth/2 + 5);
							//If tabs are not scrollable
							if(!scrollDiv){
								var leftStr = (middle  - (curElLeft) -  curElWidth/2 + 5) + "px";
								wrap.style.webkitTransform =  "translate3d("+leftStr+",0,0)" ;
							}else{
								//If scrollable tabs
								var wrapWidth = wrap.offsetWidth;
								var currentX = Math.abs(getX(scrollDiv.style.webkitTransform));
								var leftOffset = 100;
								var elementOffset = 40;
								//If tabs are reaching right end or left end
								if(((currentX + wrapWidth) < (curElLeft + curElWidth + elementOffset)) || (currentX > (curElLeft - leftOffset))){
									if(leftStr > 0){
										leftStr = 0;
									}
									//Use this scrollTo, so when scrolling tab manually will not flicker
									ionicScrollDelegate.scrollTo(Math.abs(leftStr), 0, true);
								}
							}
						}
					};
					function getX(matrix) {
						matrix = matrix.replace("translate3d(","");
						matrix = matrix.replace("translate(","");
						return (parseInt(matrix));
					}
					var events = scope.events;
					events.on('slideChange', function(data){
						setPosition(data.index);
					});
					events.on('ngRepeatFinished', function(ngRepeatFinishedEvent) {
						renderScrollableTabs();
					});

					renderScrollableTabs();
				},
				controller : function($scope, $attrs, $element) {
					$scope.events = new SimplePubSub();
					var c_index = [{index: 0 , id: 0, name: '全部'}];
					$scope.categoryList.forEach(function (obj) {
						c_index.push(obj);
					})
					var icons = angular.element('.tsb-icons').find("a");
					var initialIndex = $attrs.tab, totalTabs = icons.length;
					if(typeof $attrs.tab === 'undefined' || (totalTabs <= initialIndex) || initialIndex < 0){
						initialIndex = Math.floor(icons.length/2);
					}
					$scope.onSlideMove({"index": eval(initialIndex), cid: c_index[eval(initialIndex)].id});
					$scope.slideHasChanged = function(index){
						$scope.events.trigger("slideChange", {"index" : index});
						$timeout(function(){if($scope.onSlideMove) $scope.onSlideMove({"index" : eval(index), cid: c_index[index].id});},100);
					};

					$scope.$on('ngRepeatFinished', function(ngRepeatFinishedEvent) {
						$scope.events.trigger("ngRepeatFinished", {"event" : ngRepeatFinishedEvent});
					});
				}
			};

		}
	]);